home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Information
/
CSMP Digest
/
volume 3
/
csmp-digest-v3-106
< prev
next >
Wrap
Text File
|
1995-12-31
|
58KB
|
1,736 lines
C.S.M.P. Digest Wed, 02 Aug 95 Volume 3 : Issue 106
Today's Topics:
Creating Alias Files Example
Creating Finder Aliases without the help of the Finder ...
CursorDevices manager broken on PPC?
Gestalt Selectors List 3.0 released
How to access TmTask structure in PPC interrupt?
Source code to limit life of app
The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
The digest is a collection of article threads from the internet newsgroups
comp.sys.mac.programmer.help, csmp.tools and csmp.misc. It is designed for
people who read news semi-regularly and want an archive of the discussions.
If you don't know what a newsgroup is, you probably don't have access to
it. Ask your systems administrator(s) for details. If you don't have access
to news, you may still be able to post messages to the group by using a
mail server like anon.penet.fi (mail help@anon.penet.fi for more
information).
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr). Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The digest is officially distributed by two means, by email and ftp.
If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
help Sends you a summary of commands
subscribe csmp-digest Your Name Adds you to the mailing list
signoff csmp-digest Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.
The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu.
-------------------------------------------------------
>From andrewwelc@aol.com (AndrewWelc)
Subject: Creating Alias Files Example
Date: 12 Jul 1995 06:09:22 -0400
Organization: America Online, Inc. (1-800-827-6364)
Here's an example of some code that will create an Alias file for you.
Works like a charm, no need for AppleScript or a Scriptable Finder.
// --------------------------------------------------------------------
// -- Place an alias to this folder in the Apple Menu Items folder
void MakeFolderAlias(FSSpec *snapzFolderSpec)
{
short appleVRefNum;
long appleID;
OSErr err;
FSSpec aliasSpec;
// -- Setup the alias's FSSpec
err = FindFolder(kOnSystemDisk, kAppleMenuFolderType,
kCreateFolder, &appleVRefNum, &appleID);
BlockMove((Ptr)snapzFolderSpec, (Ptr)&aliasSpec, sizeof(FSSpec));
aliasSpec.vRefNum = appleVRefNum;
aliasSpec.parID = appleID;
// -- Next create an alias record
if (err == noErr)
{
AliasHandle aliasHandle;
err = NewAlias(nil, snapzFolderSpec, &aliasHandle);
if (err == noErr)
{
short myResFile;
FInfo aliasFInfo,theFileFInfo;
short aliasRefNum;
// -- Save the current resource file
myResFile = CurResFile();
// -- Get info on the file we are making an alias of
err = FSpGetFInfo(snapzFolderSpec, &theFileFInfo);
// -- Create and open the file.
HCreateResFile(aliasSpec.vRefNum, aliasSpec.parID, &aliasSpec.name);
if (ResError() == noErr)
{
aliasRefNum = FSpOpenResFile(&aliasSpec, fsCurPerm);
// -- If possible, write to the file
if (aliasRefNum != -1)
{
// -- Write the resource
UseResFile(aliasRefNum);
AddResource((Handle)aliasHandle, rAliasType, 0, &aliasSpec.name);
WriteResource((Handle)aliasHandle);
CloseResFile(aliasRefNum);
UseResFile(myResFile);
// -- Set the finder flags
theFileFInfo.fdFlags = 32768;
theFileFInfo.fdCreator = 'MACS';
theFileFInfo.fdType = 'fdrp';
FSpSetFInfo(&aliasSpec, &theFileFInfo);
}
}
}
}
} // -- MakeFolderAlias
Regards,
Andrew Welch
Thaumaturgist
Ambrosia Software, Inc.
..........
For the latest versions of our software, technical support, and Ambrosia
news, stop by and visit the Ambrosia Software, Inc. support forums:
America Online ---> Keyword: Ambrosia
CompuServe ---> GO word: Ambrosia
eWorld --> Shortcut: Ambrosia
---------------------------
>From iain.donaldson.1610323@bnr.ca (Iain Donaldson)
Subject: Creating Finder Aliases without the help of the Finder ...
Date: 7 Jul 1995 13:28:01 GMT
Organization: Bell-Northern Research
I am trying to create a routine that creates Finder alias files (i.e. not
just alias records, alias files containing an 'alis' resource and with the
appropriate attributes set).
I can create the file, add the 'alis' (id=0) to the file, and set the
'isAlias' flag in the file attributes. Also, for simple files such as
applications and documents I can set the type and creator correctly.
I'm really trying to make sure I can alias Folders, AppleShare volumes and
other "containers", and there seem to be a rather large list of file types
(e.g. fdrp, drop, srvr, hdsk, ....) that can be set up. The only way I can
see of generating the correct one is to spend time and effort looking at
all the various file attrributes and attempting to map the correct one to
the correct file type.
Before I embark on this laborious exercise, is there a simple way to do
this that my (partially complete) New Inside Mac set doesn't tell me ? I
have already decided to abandon another possible alternative of sending an
AEvenet to the Finder to Make an Alias as I would have to then copy/move
the alias where I want it to be and possibly delete it from where it was
created.
I'd welcome the input of any of you inspired geniuses out there who've
found an easy way around this (or even some handy C source code to prevent
my laborious recreation of other's work...;-)) ....
Cheers
..Iain
--
Iain Donaldson iainad@bnr.ca / iain@iainad.demon.co.uk
BNR Europe Ltd.
+++++++++++++++++++++++++++
>From mclow@coyote.csusm.edu (Marshall Clow)
Date: Mon, 10 Jul 1995 10:49:17 -0700
Organization: Aladdin Systems
In article <iain.donaldson.1610323-0707951427280001@bmdhm73.bnr.co.uk>,
iain.donaldson.1610323@bnr.ca (Iain Donaldson) wrote:
>I am trying to create a routine that creates Finder alias files (i.e. not
>just alias records, alias files containing an 'alis' resource and with the
>appropriate attributes set).
>
[descriptions of problems deleted]
>Before I embark on this laborious exercise, is there a simple way to do
>this that my (partially complete) New Inside Mac set doesn't tell me ?
Apple's suggested solution to this problem is:
"Send an AppleEvent to the Finder to create the alias".
The contents of alias files created by the finder are not documented. :-(
>I
>have already decided to abandon another possible alternative of sending an
>AEvenet to the Finder to Make an Alias as I would have to then copy/move
>the alias where I want it to be and possibly delete it from where it was
>created.
>
Are you complaining becase you find this hard, or just because it's
two steps? On the other hand, you are willing to reverse-engineer the file
structure to create them yourself.
Which is the easier, more compatible solution?
-- Marshall
--
"They that can give up essential liberty to obtain a little temporary
safety deserve neither liberty nor safety." -- Benjamin Franklin
_Historical Review of Pennsylvania_, 1759
+++++++++++++++++++++++++++
>From andrewwelc@aol.com (AndrewWelc)
Date: 11 Jul 1995 01:29:01 -0400
Organization: America Online, Inc. (1-800-827-6364)
> The contents of alias files created by the finder are not documented.
:-(
I didn't know that, so I went ahead and created 'em myself. Basically you
just call NewAlias() to create a new alias record, create a new file with
the type 'fdrp' and the creator 'MACS', set the finder flags to 32768
(sets the alias bit), and add the alias record to the resource fork
(resource type = rAliasType, ID = 0, resource name = aliasSpec.name).
Works like a charm. I didn't go with the AppleEvents route because 1) I'm
not too wild about the AppleEvents implementation, and 2) I couldn't
depend on a scriptable Finder being available.
Also if you think about it, Apple can't really change the format of Alias
files all that easily, otherwise there would be all kind of problems when
a user upgrades his/her system software version and all current alias
records become invalid. At the very least, they would build in backwards
compatibility.
Regards,
Andrew Welch
Thaumaturgist
Ambrosia Software, Inc.
..........
For the latest versions of our software, technical support, and Ambrosia
news, stop by and visit the Ambrosia Software, Inc. support forums:
America Online ---> Keyword: Ambrosia
CompuServe ---> GO word: Ambrosia
eWorld --> Shortcut: Ambrosia
+++++++++++++++++++++++++++
>From iain.donaldson.1610323@bnr.ca (Iain Donaldson)
Date: 11 Jul 1995 18:35:30 GMT
Organization: Bell-Northern Research
In article <mclow-1007951049170001@ciscots1-3.csusm.edu>,
mclow@coyote.csusm.edu (Marshall Clow) wrote:
> Apple's suggested solution to this problem is:
> "Send an AppleEvent to the Finder to create the alias".
>
> The contents of alias files created by the finder are not documented. :-(
I thought it was the contents of 'Alias records' that were not documented
? I don't care about these as the OS happily creates them for me. It's the
file type/creator's that I need to create for container (folder/floppy)
types - i.e. how to tell if it is a folder, an appleshare volume, a hard
disk, a floppy, a mounted appleshare volume, an apple mailbox etc. I
thought I may have missed an easy way to get this info. and just wanted to
check before I spent hours poring through NIM and then even more hours bit
masking and debugging ...
> >I
> >have already decided to abandon another possible alternative of sending an
> >AEvenet to the Finder to Make an Alias as I would have to then copy/move
> >the alias where I want it to be and possibly delete it from where it was
> >created.
> >
> Are you complaining becase you find this hard, or just because it's
> two steps? On the other hand, you are willing to reverse-engineer the file
> structure to create them yourself.
>
> Which is the easier, more compatible solution?
I'm not complaining because it's hard, but because it doesn't really meet
my crietia - e.g. what happens if the file is on a locked volume ? I don't
want the user to see a messy dialog in between asking for the alias to be
created and actually getting it - especially if the dialog isn't very
relevant ("Alias will be created on the Desktop"). If the Finder had an
event for creating an alias with an alias/path as to where to create it,
I'd be happy (retrospectively from System 7.0, of course ;-) ...)
Oh well, looks like some effort with PBGetCatInfo and lots of bit masking
coming up ...
..Iain
--
Iain Donaldson iainad@bnr.ca / iain@iainad.demon.co.uk
BNR Europe Ltd.
+++++++++++++++++++++++++++
>From ldo@waikato.ac.nz (Lawrence D9Oliveiro)
Date: Wed, 12 Jul 1995 17:33:09 +1200
Organization: University of Waikato
In article <iain.donaldson.1610323-1107951935090001@bmdhm73.bnr.co.uk>,
iain.donaldson.1610323@bnr.ca (Iain Donaldson) wrote:
>In article <mclow-1007951049170001@ciscots1-3.csusm.edu>,
>mclow@coyote.csusm.edu (Marshall Clow) wrote:
>
>> Apple's suggested solution to this problem is:
>> "Send an AppleEvent to the Finder to create the alias".
>
>> >I
>> >have already decided to abandon another possible alternative of sending an
>> >AEvenet to the Finder to Make an Alias as I would have to then copy/move
>> >the alias where I want it to be and possibly delete it from where it was
>> >created.
>> >
>> Are you complaining becase you find this hard, or just because it's
>> two steps? On the other hand, you are willing to reverse-engineer the file
>> structure to create them yourself.
>>
>> Which is the easier, more compatible solution?
>
>I'm not complaining because it's hard, but because it doesn't really meet
>my crietia - e.g. what happens if the file is on a locked volume ?
So create the alias directly where you want it. I just mounted a read-only
volume, and tried the following script:
tell application "Finder"
make new alias at startup disk to alias "Greed:Site Licence:"
end tell
Worked like a charm. Hint: you can also specify your own name for the
alias when you create it.
Lawrence
scriptability fanatic and Object Model cheerleader
+++++++++++++++++++++++++++
>From iain.donaldson.1610323@bnr.ca (Iain Donaldson)
Date: 12 Jul 1995 12:04:50 GMT
Organization: Bell-Northern Research
In article <3tt26t$ctj@newsbf02.news.aol.com>, andrewwelc@aol.com
(AndrewWelc) wrote:
> > The contents of alias files created by the finder are not documented.
> :-(
>
> I didn't know that, so I went ahead and created 'em myself. Basically you
> just call NewAlias() to create a new alias record, create a new file with
> the type 'fdrp' and the creator 'MACS', set the finder flags to 32768
> (sets the alias bit), and add the alias record to the resource fork
> (resource type = rAliasType, ID = 0, resource name = aliasSpec.name).
>
> Works like a charm. I didn't go with the AppleEvents route because 1) I'm
> not too wild about the AppleEvents implementation, and 2) I couldn't
> depend on a scriptable Finder being available.
>
Andrew:
Does this mean that you don't have to bother setting the container types
to anything other than 'fdrp' (e.g. 'hdsk', 'fdsk', 'srvr' etc.) ? Also,
do you find that the ICONs for the new Alias file are OK, or do you need
to copy across the icon from the old file and set the custom icon flag ?
(my icons seem to disappear until you use the alias for the first time).
Cheers
..Iain
--
Iain Donaldson iainad@bnr.ca / iain@iainad.demon.co.uk
BNR Europe Ltd.
+++++++++++++++++++++++++++
>From iain.donaldson.1610323@bnr.ca (Iain Donaldson)
Date: 12 Jul 1995 17:24:26 GMT
Organization: Bell-Northern Research
In article <ldo-1207951733090001@130.217.96.144>, ldo@waikato.ac.nz wrote:
> So create the alias directly where you want it. I just mounted a read-only
> volume, and tried the following script:
>
> tell application "Finder"
> make new alias at startup disk to alias "Greed:Site Licence:"
> end tell
>
> Worked like a charm. Hint: you can also specify your own name for the
> alias when you create it.
>
So does this require the scriptable FInder (7.5) or work with 7.0 ? My
AppleEvent Registry for the standard Finder suite doesn't indicate I can
pass info for the file to be created (for system 7.0/.1).
..Iain
--
Iain Donaldson iainad@bnr.ca / iain@iainad.demon.co.uk
BNR Europe Ltd.
+++++++++++++++++++++++++++
>From Michael_Hecht@mac.sas.com (Michael Hecht)
Date: Thu, 13 Jul 1995 13:58:53 GMT
Organization: SAS Institute Inc.
> In article <ldo-1207951733090001@130.217.96.144>, ldo@waikato.ac.nz wrote:
>
>
> > So create the alias directly where you want it. I just mounted a read-only
> > volume, and tried the following script:
> >
> > tell application "Finder"
> > make new alias at startup disk to alias "Greed:Site Licence:"
> > end tell
> >
> > Worked like a charm. Hint: you can also specify your own name for the
> > alias when you create it.
> >
It's also kinda hard to get the Finder to listen to an AppleEvent from
your Drag Manager SendData callback procedure, since you're not supposed
to process-switch within that routine. That's why I create the file myself
in my code.
Actually, I would prefer for Apple to just make a "MakeAliasFile" toolbox
call for me, so I wouldn't have to worry about compatibility.
--Michael
=====================================================================
Michael P. Hecht Michael_Hecht@mac.sas.com
SAS Institute Inc.; Cary, NC USA AppleLink: SAS.HECHT
---------------------------
>From james@clyde.as.utexas.edu (James McCartney)
Subject: CursorDevices manager broken on PPC?
Date: 14 Jul 1995 22:48:48 GMT
Organization: Univ of Texas at Austin, Astronomy
I am trying to port some code to PowerPC that moves the mouse.
(Don't recite HIG to me ..)
CursorDevices.h contains the following warning:
/*
* * * W A R N I N G * * *
On currently shipping PowerMacs, the CursorDevices manager is implemented
in 68K code and emulated. Unfortunately, the MixedMode glue in InterfaceLib
is incorrect. It and the 1.0 version of this file had incorrect parameter
lists for most functions.
As a first step to avoid runtime errors, the functions in this file were
renamed (e.g. from"CrsrDevButtons" to "CursorDeviceButtons"). This will result
in a link time error if a PowerPC application tries to call the functions.
When InterfaceLib is fixed, the new names will be exported and PowerPC
code will then be able to call them.
*/
As it says, I'm unable to link to the new functions on the PowerPC. The
68K version links OK. Are the old name functions really unusable? Can
I declare them myself, link to them and use them OK? How do I move the
mouse on the PowerPC in native code?
I am using Codewarrior.
--- james mccartney james@astro.as.utexas.edu
+++++++++++++++++++++++++++
>From jwbaxter@olympus.net (John W. Baxter)
Date: Fri, 14 Jul 1995 21:52:29 -0700
Organization: Internet for the Olympic Peninsula
In article <james-1407951749490001@mice.as.utexas.edu>,
james@clyde.as.utexas.edu (James McCartney) wrote:
> As it says, I'm unable to link to the new functions on the PowerPC. The
> 68K version links OK. Are the old name functions really unusable? Can
> I declare them myself, link to them and use them OK? How do I move the
> mouse on the PowerPC in native code?
>
> I am using Codewarrior.
You might consider a 68K CODE resource which makes the calls that move the
cursor, which you in turn call through a routine descriptor. I haven't
done this, but until there's a new InterfaceLib for PPC, it seems like a
useable workaround.
--John
--
John Baxter Port Ludlow, WA, USA [West shore, Puget Sound]
I don't do windows.
jwbaxter@pt.olympus.net
+++++++++++++++++++++++++++
>From d88-bli@xbyse.nada.kth.se (Bo Lindbergh)
Date: 18 Jul 1995 06:07:41 GMT
Organization: Royal Institute of Technology, Stockholm, Sweden
In article <james-1407951749490001@mice.as.utexas.edu> james@clyde.as.utexas.edu (James McCartney) writes:
>
> As it says, I'm unable to link to the new functions on the PowerPC. The
> 68K version links OK. Are the old name functions really unusable?
Only half of them. :-/
> Can I declare them myself, link to them and use them OK? How do I move
> the mouse on the PowerPC in native code?
You need something like this:
#if ! CFMSYSTEMCALLS
enum {
uppCursorDeviceMoveToProcInfo =
kD0DispatchedPascalStackBased |
DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(kTwoByteCode) |
RESULT_SIZE(SIZE_CODE(sizeof (OSErr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(1,SIZE_CODE(sizeof (CursorDevicePtr))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(2,SIZE_CODE(sizeof (long))) |
DISPATCHED_STACK_ROUTINE_PARAMETER(3,SIZE_CODE(sizeof (long)))
};
pascal OSErr CursorDeviceMoveTo(
CursorDevicePtr ourDevice,
long absX,
long absY)
{
return CallUniversalProc(
GetToolboxTrapAddress(_CursorDeviceDispatch),
uppCursorDeviceMoveToProcInfo,
1, /* selector code */
ourDevice,absX,absY); /* actual parameters */
}
#endif
Repeat the above for each function, varying the selector code and the
procinfo appropriately.
("How do I call a trap that has no PowerPC glue available (yet)?" is
getting to be a FAQ. I'd better make Chris and Jon happy by writing an
answer section....)
/Bo Lindbergh
---------------------------
>From rgaros@bio.vu.nl (Rene G.A. Ros)
Subject: Gestalt Selectors List 3.0 released
Date: 13 Jul 1995 09:17:41 +0200
Organization: VU Biology, Amsterdam, The Netherlands
Dear Mac-programmers,
Today I released version 3.0 of the
Gestalt Selectors List (GSL)
It lists all sorts of information about the Gestalt Manager, but mainly
about selectors and the meaning of the returned values.
The Gestalt Manager is part of the Apple Macintosh System Software to
enable programmers to determine the availability of certain software and
hardware.
You can obtain the latest version in several ways:
- by sending email to the mail archive server at:
gestalt-selectors-list-request@bio.vu.nl
with the subject:
archive get recent/gestalt-selectors.etx
or to get the compressed version:
archive get recent/gestalt-selectors.sit.hqx
- FTP to the info-mac archives at sumex-aim.stanford.edu and get the file
/info-mac/dev/info/gestalt-selectors-30.hqx
You can also use any of its mirror sites.
- World Wide Web
The GSL is available, behind the editor's home-page, at:
http://www.bio.vu.nl/home/rgaros/gestalt/
It is also available, together with other Macintosh FAQs, at:
http://www.astro.nwu.edu/lentz/mac/faqs/source/gestalt.html
Also, on the Apple WWW site in:
http://www.info.apple.com/cgi-bin/lister-pl?Apple.Support.Area/
Developer_Services/Tool_Chest/OS_Utilities
- America OnLine
You can find the GSL on AOL in the "MDV/Documents and Proposals" directory.
- AppleLink
The GSL can be found on AppleLink at this location:
Developer Support:Developer Services:Tool Chest:OS/Toolbox:
- CompuServe members can find it at the Macintosh Developers Forum
(GO MACDEV) in the Tools/Debuggers (13) section.
Or use the Internet locations by using GO INTERNET.
- eWorld
You can find the GSL on eWorld in this location:
Apple Developer Services:Tool Chest:OS/Toolbox:
The shortcut to Apple Developer Services is 'devservice'.
- CD-ROM
The GSL is included, with permission, on these CD-ROMs:
Apprentice CD-ROM (Celestin Company)
BBS in a BOX CD-ROM (Arizona Macintosh Users Group)
Bookmark CD (Apple Computer, Inc.)
Developer CD Series, Tool Chest (Apple Computer, Inc.)
Info-Mac CD-ROM (Pacific HiTech, Inc.)
The Right Stuffed CD-ROM (Quantum Leap Technologies, Inc.)
(NOTE: Tool Chest CD since May 1995, Bookmark starting with #23)
- Subscribers of the maillist have received their copy already.
If you want to join this list you need to send a request to:
gestalt-selectors-list-request@bio.vu.nl
with in the subject line 'subscribe'. You will then also receive
several updates before the next version is released. This list is
only for distribution, not for discussion.
Contributions (new info, remarks, etc.) for the list can be send to:
gestalt-selectors-list@bio.vu.nl
Please, be aware that it may take a couple of days before the new version
is available at all these locations. It is available immediatly by using
the mail archive server.
Beside a large number of new and changed selectors, these are the major
changes since the previous version:
***************************************************************************
Includes information from the WWDC Technology CD-ROM, like the
Preliminary Copland Headers.
Also new are the machine types for several unreleased PowerMacs. And the
selectors and responses new with System 7.5.2.
Added selectors
Apple System : danm, nreg, opfw, nvsv, unic, wind
Apple Add. : calb
Third Parties : InMn, MFK+
Added unknown
Apple Softw. : ??? , cnfn, fndv, bclk, gacc, pclk, pwky, rmbg, wnkl
Third Parties : 5mat, ATR , CDFL, DDCD, DDJB, DPin, KBCM, MOMM, OLE2,
SLIP, sMon, URLf, YAWN
Changed selectors
Apple System : aslm, cmtc, dply, hdwr, mach, powr, qd , qd3d, snhw,
tele, thds, tsmv, vers, vm
Changed unknown
Apple Softw. : fndx, iic , serh
Previously unknown
Apple System : afps, fnd , fnd^, iic
Apple Add. : otan
Third Parties : Frs1, FrsH
***************************************************************************
Best regards,
Rene Ros
rgaros@bio.vu.nl
--
Rene G.A. Ros rgaros@bio.vu.nl
Amsterdam, The Netherlands http://www.bio.vu.nl/home/rgaros/
- ------------------------------------------------------------------------------
Recommended reading: The UnDutchables (ISBN 0-9625006-3-1)
---------------------------
>From madole@mills.edu (David Madole)
Subject: How to access TmTask structure in PPC interrupt?
Date: 7 Jul 1995 06:35:03 GMT
Organization: University of California, Berkeley
NIM goes into how to access the fields in the TmTask structure in the
68k version of the Time Manager (get the address from Register A1), but
how do I do so in PPC interrupt code? I need to use the trick of
passing the address of a structure that has a TmTask at the beginning
and "more" after the TmTask structure. Is it actually passed to the
interrupt routine as an argument or something like that?
This is probably really a Mixed Mode Manager question.
Thanks in advance,
Dave
Dave Madole
Technical Director, Center for Contemporary Music
Mills College
510-430-2336
madole@mills.edu
+++++++++++++++++++++++++++
>From scouten@metrowerks.com (Eric Scouten)
Date: Fri, 07 Jul 1995 01:55:23 -0500
Organization: Metrowerks, Inc.
In article <3tikio$g34@agate.berkeley.edu>, madole@mills.edu wrote:
> NIM goes into how to access the fields in the TmTask structure in the
> 68k version of the Time Manager (get the address from Register A1), but
> how do I do so in PPC interrupt code? I need to use the trick of
> passing the address of a structure that has a TmTask at the beginning
> and "more" after the TmTask structure. Is it actually passed to the
> interrupt routine as an argument or something like that?
Yup. You can write...
pascal void MyTimerCallback(TMTaskPtr tmTaskPtr)
{
// whatever
}
...and it will work if you've done the UPP stuff correctly. That can be as
simple as...
static TimerUPP myTimerCallbackUPP = NewTimerProc(MyTimerCallback);
and passing the value of myTimerCallbackUPP in the TMTask record.
BTW, in CodeWarrior you can have the 68K version fetch the parameter
directly from A1 without any special shenanigans. Write:
#if GENERATINGCFM
pascal void MyTimerCallback(TMTaskPtr tmTaskPtr)
#else
pascal void MyTimerCallback(TMTaskPtr tmTaskPtr : __A1)
#endif
{
// whatever
}
-es
__________________________________________________________________________
Eric Scouten Constructor Constructor
scouten@metrowerks.com Metrowerks, Inc.
They're my feet and I'll put them in my mouth if I want to.
+++++++++++++++++++++++++++
>From Richard Wesley <hawkfish@punchdeck.com>
Date: 7 Jul 1995 15:26:21 GMT
Organization: Punch Deck Consulting
madole@mills.edu (David Madole) wrote:
>NIM goes into how to access the fields in the TmTask structure in the
>68k version of the Time Manager (get the address from Register A1), but
>how do I do so in PPC interrupt code? I need to use the trick of
>passing the address of a structure that has a TmTask at the beginning
>and "more" after the TmTask structure. Is it actually passed to the
>interrupt routine as an argument or something like that?
>
>This is probably really a Mixed Mode Manager question.
In CW6 I do the following:
class CTimeTask {
..
typedef struct {
TMTask mTask;
CTimeTask *mOwner;
} TMTaskExt;
static void TimerProc (TMTaskExt *inTaskExt);
TMTaskExt mTaskExt;
};
CTimeTask::CTimeTask (void)
{
mTaskExt.mTask.tmAddr = NewTimerProc (TimerProc);
mTaskExt.mOwner = this;
::InsTime ((QElemPtr) &mTaskExt);
}
CTimeTask::~CTimeTask (void)
{
::RmvTime ((QElemPtr) &mTaskExt);
DisposeRoutineDescriptor (mTaskExt.mTask.tmAddr);
mTaskExt.mTask.tmAddr = nil;
}
#if !GENERATINGCFM
#pragma parameter TaskProc (__A1)
#endif
void
CTimeTask::TimerProc (TMTaskExt *inTaskExt)
{
..
}
This should compile correctly for both sets of hardware. Small caveat:
I have not actually tested this code (I wrote it yesterday) but the same
thing works correctly for Deferred Tasks, so I assume this will work the
same way.
- rmgw
http://www.punchdeck.com/hawkfish/Resume.html
- --------------------------------------------------------------------------
Richard Wesley hawkfish@punchdeck.com | "'Hand it round first, and cut it
Punch Deck Consulting pnchdeck@aol.com | afterwards.'" - Lewis Carroll,
Macintosh Software Development | "Through the Looking Glass"
- --------------------------------------------------------------------------
+++++++++++++++++++++++++++
>From stevec@jolt.mpx.com.au (Stephen Coy)
Date: Sun, 16 Jul 1995 11:50:16 +1000
Organization: Resolve Software Pty Ltd
In article <3tjjmt$69r@news.halcyon.com>, Richard Wesley
<hawkfish@punchdeck.com> wrote:
> madole@mills.edu (David Madole) wrote:
> >NIM goes into how to access the fields in the TmTask structure in the
> >68k version of the Time Manager (get the address from Register A1), but
> >how do I do so in PPC interrupt code? I need to use the trick of
> >passing the address of a structure that has a TmTask at the beginning
> >and "more" after the TmTask structure. Is it actually passed to the
> >interrupt routine as an argument or something like that?
> >
> >This is probably really a Mixed Mode Manager question.
>
> In CW6 I do the following:
>
<one possible solution snipped>
>
> This should compile correctly for both sets of hardware. Small caveat:
> I have not actually tested this code (I wrote it yesterday) but the same
> thing works correctly for Deferred Tasks, so I assume this will work the
> same way.
>
> - rmgw
Another easier way to do this is to privately inherit from the TMTask
structure itself. This provides a typesafe and reliable way to implement
timers whose behaviour is dictated by a virtual member function.
class MTimer: private TMTask
{
public:
void Prime(Milliseconds count);
// Inserts the TMTask into the time manager queue and primes the timer
void Unprime();
// Removes the TMTask from the time manager queue
protected:
MTimer();
// Inserts the task in the queue
~MTimer();
// Removes the timer from the queue
private:
virtual void DoTimerCompletion() = 0;
// Must be overridden to provide desired functionality
#if GENERATINGCFM
static pascal void TimerCompletion(MTimer* );
static RoutineDescriptor fgTimerCompletionRoutineDescriptor;
inline static TimerUPP GetTimerCompletionFn() { return
&fgTimerCompletionRoutineDescriptor; }
#else
static pascal void TimerCompletion(MTimer* aTask: __A1);
inline static TimerUPP GetTimerCompletionFn() { return
(Register68kProcPtr)TimerCompletion; }
const long fA5;
#endif
Boolean fIsInstalled;
};
#if GENERATINGCFM
RoutineDescriptor MTimer::fgTimerCompletionRoutineDescriptor
= BUILD_ROUTINE_DESCRIPTOR(uppTimerProcInfo, MTimer::TimerCompletion);
#endif
#pragma segment Main
MTimer::MTimer()
: fIsInstalled(false)
#if !GENERATINGCFM
,fA5(SetCurrentA5())
#endif
{
tmAddr = GetTimerCompletionFn();
}
#pragma segment Main
void MTimer::Unprime()
{
RmvTime((QElemPtr)this);
fIsInstalled = false;
}
#pragma segment Main
MTimer::~MTimer()
{
if (fIsInstalled)
RmvTime((QElemPtr)this);
}
#pragma segment Main
void MTimer::Prime(Milliseconds count)
{
tmCount = tmWakeUp = tmReserved = 0;
InsTime((QElemPtr)this);
fIsInstalled = true;
PrimeTime((QElemPtr)this, count);
}
#pragma segment Main
#if GENERATINGCFM
pascal void MTimer::TimerCompletion(MTimer* theTask)
{
theTask->fIsInstalled = false;
RmvTime((QElemPtr)theTask);
theTask->DoTimerCompletion();
}
#else
pascal void MTimer::TimerCompletion(MTimer* theTask: __A1)
{
long currentA5 = SetA5(theTask->fA5);
theTask->fIsInstalled = false;
RmvTime((QElemPtr)theTask);
theTask->DoTimerCompletion();
SetA5(currentA5);
}
... and apologies for posting actual source to this group, but this
example was so short that I couldn't resist :)
Regards
--
Steve Coy
Resolve Software Pty Ltd
4 Andove St
Belrose NSW 2085
Australia
+++++++++++++++++++++++++++
>From Richard Wesley <hawkfish@punchdeck.com>
Date: 16 Jul 1995 21:19:35 GMT
Organization: Punch Deck Consulting
stevec@jolt.mpx.com.au (Stephen Coy) wrote:
>In article <3tjjmt$69r@news.halcyon.com>, Richard Wesley
><hawkfish@punchdeck.com> wrote:
>> madole@mills.edu (David Madole) wrote:
>> >NIM goes into how to access the fields in the TmTask structure in the
>> >68k version of the Time Manager (get the address from Register A1), but
>> >how do I do so in PPC interrupt code? I need to use the trick of
>> >passing the address of a structure that has a TmTask at the beginning
>> >and "more" after the TmTask structure. Is it actually passed to the
>> >interrupt routine as an argument or something like that?
>> >
>> >This is probably really a Mixed Mode Manager question.
>>
>> In CW6 I do the following:
>
> <one possible solution snipped>
>
>> This should compile correctly for both sets of hardware. Small caveat:
>> I have not actually tested this code (I wrote it yesterday) but the same
>> thing works correctly for Deferred Tasks, so I assume this will work the
>> same way.
>>
>> - rmgw
>
>Another easier way to do this is to privately inherit from the TMTask
>structure itself. This provides a typesafe and reliable way to implement
>timers whose behaviour is dictated by a virtual member function.
>
> <another solution snipped>
Steve and I just had a pleasant email chat in which we admired each other's
code and discussed one or two things that are probably of general interest
to this thread:
1) The inheritance trick is pretty generally useful and it might be
nice to have a set of objects that are derived from other TB structures like
FSSpec (where to put that pesky full pathname routine we all have lying around)
and ParamBlockRec (never forget about A5 again...)
2) I gave Steve a copy of my atomic semaphore class to replace the Boolean
member which has a small reentrancy window in Prime:
#pragma once
class CSemaphore {
public:
CSemaphore (Boolean inState = false)
{mQueue.qHead = mQueue.qTail = nil; if (!inState) Unlock ();};
OSErr Lock (void) {return ::Dequeue (&mElem, &mQueue);};
void Unlock (void) {if (!mQueue.qHead) ::Enqueue (&mElem, &mQueue);};
protected:
QHdr mQueue;
QElem mElem;
};
Useage:
#include "CSemaphore.h"
CSemaphore s;
if (s.Lock ()) {
// Didn't get resource
} // if
else {
//got resource
s.Unlock ();
} // else
- rmgw
http://www.punchdeck.com/hawkfish/PunchDeck.html
- --------------------------------------------------------------------------
Richard Wesley hawkfish@punchdeck.com | "'Hand it round first, and cut it
Punch Deck Consulting pnchdeck@aol.com | afterwards.'" - Lewis Carroll,
Macintosh Software Development | "Through the Looking Glass"
- --------------------------------------------------------------------------
---------------------------
>From rvtaylor@netcom.com (Richard Taylor)
Subject: Source code to limit life of app
Date: Fri, 30 Jun 1995 21:10:29 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
I have had a couple of betas that "expire" at a certain point after being
installed. Has anyone seen any source code used to accomplish this? I
assume that the expiration function is not so dumb as to be fooled by
someone changing the system date after. Can anyone point me in the right
direction on this?
Richard Taylor
--
richard taylor: rvtaylor@netcom.com
+++++++++++++++++++++++++++
>From tulip@tiac.net (Ed Anson)
Date: Fri, 30 Jun 1995 20:38:11 -0400
Organization: Tulip Software
In article <rvtaylorDB085H.AtD@netcom.com>, rvtaylor@netcom.com (Richard
Taylor) wrote:
> I have had a couple of betas that "expire" at a certain point after being
> installed. Has anyone seen any source code used to accomplish this? I
> assume that the expiration function is not so dumb as to be fooled by
> someone changing the system date after. Can anyone point me in the right
> direction on this?
As you pointed out, any expiration mechanism can be vulnerable to hacking.
I have hacked a few in my time.
I have also implemented an expiration mechanism that resists hacking to
some extent. As you might guess, its resistance to hacking relies (to some
extent) on the secrecy of the mechanism. In other words, my mechanism is a
trade secret. I suspect that anyone with a credible mechanism will want to
keep it secret.
Of course, for a suitable fee (under a non-disclosure agreement), I could help.
- --------------------
Ed Anson MediaTree: multimedia outline editor & catalog
Tulip Software
Andover, MA 01810 For details, check out my WWW page:
U.S.A. <http://www.tiac.net/users/tulip/home.html>
+++++++++++++++++++++++++++
>From howlett@netcom.com (J. Scott Howlett)
Date: Sat, 1 Jul 1995 00:12:59 GMT
Organization: Netcom Online Communications Services (408-241-9760 login: guest)
In article <...> rvtaylor@netcom.com (Richard Taylor) writes:
>I have had a couple of betas that "expire" at a certain point after being
>installed. Has anyone seen any source code used to accomplish this? I
>assume that the expiration function is not so dumb as to be fooled by
>someone changing the system date after. Can anyone point me in the right
>direction on this?
>
The first time you notice you are being run beyond your desired date, you
should put up a dialog notifying the user what's up. If you want to be nice,
you just display the message and let them continue working. If you want to
be less nice, you quit after the dialog is dismissed. To be a little more
robust, you might set a flag in a resource somewhere the first time you
notice that the date is wrong and look at the flag, so the user can't just
set the clock back and use the program again (unless they have another copy
which they have not yet used). To be more evil, you could kill your app
when you notice the date, either by removing all your resources or by
setting your data fork and resource fork EOF to 0.
Whatever you do, though, MAKE SURE YOU REMOVE IT in the final product (test
for it explicitly!) Accidentally leaving in a time bomb is very embarrassing
for a software developer, and it happens more frequently than it should.
--
Scott Howlett
Storm Software, Inc.
howlett@netcom.com
+++++++++++++++++++++++++++
>From howlett@netcom.com (J. Scott Howlett)
Date: Sat, 1 Jul 1995 02:36:50 GMT
Organization: Netcom Online Communications Services (408-241-9760 login: guest)
In article <...> tulip@tiac.net (Ed Anson) writes:
...
>trade secret. I suspect that anyone with a credible mechanism will want to
>keep it secret.
...
Many schemes fail because any half-witted user can still keep a
backup of the software and reinstall it with the clock set back.
I suppose if you wanted to guard against this, you could write a prefs file
which tells that particular version of your app never to run again. But if
you do this in a nice way (putting it in the Prefs folder in a file or
folder with your app's name), it's easy to circumvent. If you do it in a
not-so-nice way, you probably oughtn't to be doing it.
Time-bombing betas seems like one of those things which you should put a
little effort into, but not a lot. It's usually not like you're guarding
trade secrets or NSA spy data or anything. You're typically just preventing
piracy of "free" or buggy versions of your software, or providing your
beta testers with a gentle reminder that they are running code which is
by now crusty and moldy :-)
--
Scott Howlett
Storm Software, Inc.
howlett@netcom.com
+++++++++++++++++++++++++++
>From peter@mail.peter.com.au (Peter N Lewis)
Date: Thu, 06 Jul 1995 13:34:45 +0800
Organization: Curtin University
In article <howlettDB0n9E.8pw@netcom.com>, howlett@netcom.com (J. Scott
Howlett) wrote:
>beta testers with a gentle reminder that they are running code which is
>by now crusty and moldy :-)
What, you mean it doesn't start that way? Damn, I knew I was doing
something wrong!
>Time-bombing betas seems like one of those things which you should put a
>little effort into, but not a lot.
Yup, I just use a feature of pascal, "compsecs" which returns the date the
application was compiled. I use that and the vers resource and the
current date on the Mac. If the vers resource says it's a non-final
version, and the date is N months after the compile time, then I notify
the user and if it's N+M months, I refuse to run.
But I deliberately dont want the program disabling itself, and
deliberately do tell the user they can set back their clocks to make it
work, because my main program is an FTP client, and if they want to get
the new version, they need a working version first :-)
Peter.
+++++++++++++++++++++++++++
>From nick+@pitt.edu ( nick.c )
Date: 6 Jul 1995 15:32:35 GMT
Organization: The Pitt, Chemistry
In article <peter-0607951334450001@rocky.curtin.edu.au>,
peter@mail.peter.com.au (Peter N Lewis) wrote:
>Yup, I just use a feature of pascal, "compsecs" which returns the date the
>application was compiled. I use that and the vers resource and the
>current date on the Mac. If the vers resource says it's a non-final
>version, and the date is N months after the compile time, then I notify
>the user and if it's N+M months, I refuse to run.
Each time through the loop consider logging the computer time
to the preferences file, if the computer time on a launch
is before the last loged time, the program should get
suspicious.
Also, consider having the program check if the computer time
is before the modification date on the "finder preferences"
file - if so the program should get suspicious. Odds are
no ones going to think about, or want to, delete their finder
preferences, but it get's modified so often that it's mod
date is a pretty accurate guess as to the "real" time,
even if joe user set's his clock back one month.
I like the idea of having the computer use the compile time
as a zero reference. Saves headache of having to calculate
the exact seconds from Jan 1, 1904 to the date you want things
to happen each time, and means you don't have to change
that value with each release. Neat.
>But I deliberately dont want the program disabling itself, and
>deliberately do tell the user they can set back their clocks to make it
>work, because my main program is an FTP client, and if they want to get
>the new version, they need a working version first :-)
Maybe not disable itself, but I agree with an earlier
poster that the first time the program gets suspicious
it should toggle an irreversible flag. eg, have an
extra DITL resource, and when the program gets suspicious
delete it (or toggle a "delete the DITL resource 128 first
time the program isn't locked" flag in the preferences
file if it finds the program innacessible.) What you
choose to do when your program sees that flag is up to
you, but it makes it harder for the user to lie to the
program about the date.
I would discourage people from creating more invisible
files in the preferences folder. I tend to delete
'em on principle.
---------------------= Nicholas C. DeMello =--------------------
Internet: nick+@pitt.edu _/ _/ _/ _/_/_/ _/ _/
eWorld: nick _/_/ _/ _/ _/ _/ _/_/_/
CIS: 71232,766 _/ _/_/ _/ _/ _/ _/
http://www.pitt.edu/~nick/ _/ _/ _/ _/_/_/ _/ _/
+++++++++++++++++++++++++++
>From peter@stairways.com.au (Peter N Lewis)
Date: Fri, 07 Jul 1995 10:57:01 +0800
Organization: Stairways Software
In article <rvtaylorDB085H.AtD@netcom.com>, rvtaylor@netcom.com (Richard
Taylor) wrote:
>I have had a couple of betas that "expire" at a certain point after being
>installed. Has anyone seen any source code used to accomplish this? I
>assume that the expiration function is not so dumb as to be fooled by
>someone changing the system date after. Can anyone point me in the right
>direction on this?
Well, this code certainly is that dumb, but thats my intention. The
purpose of the expirey code is to convince my silly beta testers to update
to the current version.
I don't know if C has an equivalent of compsecs (the time that the
compilcation took place). Note that this code uses the later of the
compilation date that is passed to it as a parameter and the compilation
date of this file. Usuaully I call it from the main code and that file is
compiled fairly often.
Note also that this code uses fixed strings, not in resources - since this
is only displayed on expired beta versions, I dont see any problem with
not localizing them.
Naturally, it uses other modules, some of which may be abvailable at my
ftp site:
ftp://ftp.amug.org/pub/peterlewis/
ftp://redback.cs.uwa.edu.au/Others/PeterLewis/
ftp://ftp.share.com/pub/peterlewis/
ftp://ftp.nig.ac.jp/pub/mac/PeterLewis/
ftp://nic.switch.ch/software/mac/peterlewis/
Enjoy,
Peter.
unit MyExpiry;
interface
uses
Types;
function ExpiredVersion (cs:longInt; notify, expire: integer): boolean;
{ Pass it compsecs, and the number of months until it notifies/expires }
implementation
uses
OSUtils, MyStrings, MyVersionResource, MyEmergencyNotifier, MyUtils;
function ExpiredVersion (cs:longInt; notify, expire: integer): boolean;
var
date, diff: longInt;
vers: versionRecord;
begin
ExpiredVersion := false;
GetVersion(vers);
if vers.devcode <> $80 then begin
GetDateTime(date);
if compsecs > cs then begin
cs := compsecs;
end;
diff := (date - cs) div 2678400;
if diff >= expire then begin
EmergencyNotify('This developmental version has expired. Set
your clock back, or get a new version');
ExpiredVersion := true;
end
else if diff >= notify then begin
EmergencyNotify('This developmental version has expired. It
will work for a while, and then stop working forever. Get a new
version');
end;
end;
end;
end.
--
The best book I've read recently is "Quarantine" by Greg Egan
+++++++++++++++++++++++++++
>From chrisman@ucdmath.ucdavis.edu (Mark Chrisman)
Date: Sun, 09 Jul 1995 05:51:37 -0700
Organization: University of California, Davis
One thing you can do is delete the application itself!
(There's a cute program somewhere called Cheshire Cat which demonstrates this.)
--
Mark Chrisman
+++++++++++++++++++++++++++
>From nick+@pitt.edu ( nick.c )
Date: Sun, 09 Jul 1995 12:57:52 -0500
Organization: The Pitt, Chemistry
In article <chrisman-0907950551370001@modem171.ucdavis.edu>,
chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
>One thing you can do is delete the application itself!
>
>(There's a cute program somewhere called Cheshire Cat which demonstrates this.)
I remember that one, was the code for that ever made
available? It was a neat effect, and I don't know
how one would do that - since the program would have
to quit itself before deleting itself.
---------------------= Nicholas C. DeMello =--------------------
Internet: nick+@pitt.edu _/ _/ _/ _/_/_/ _/ _/
eWorld: nick _/_/ _/ _/ _/ _/ _/_/_/
CIS: 71232,766 _/ _/_/ _/ _/ _/ _/
http://www.pitt.edu/~nick/ _/ _/ _/ _/_/_/ _/ _/
+++++++++++++++++++++++++++
>From "Marjorie L. Rhyne" <mrhyne@phenix.pdial.interpath.net>
Date: 10 Jul 1995 04:50:28 GMT
Organization: Interpath -- Providing Internet access to North Carolina
> >One thing you can do is delete the application itself!
> >
> >(There's a cute program somewhere called Cheshire Cat which demonstrates this.)
>
>
> I remember that one, was the code for that ever made
> available? It was a neat effect, and I don't know
> how one would do that - since the program would have
> to quit itself before deleting itself.
>
>
I haven't tried it but I don't think you would have many problems with a coding a
program to delete itself. You should be able to do it by either using appleevents
or by closing the resource fork of the application,this only applies to 68k
programs, after first creating a block of mem with the code to delete the program
in it. Just write a self-sufficient procedure witch does the deleting - including
the closeres call, call newptr with the size of the procedure, then do a block move
to move it, then just jump to your detached procedure.
+++++++++++++++++++++++++++
>From hnsngr@sirius.com (Ron Hunsinger)
Date: Mon, 10 Jul 1995 02:02:32 -0700
Organization: ErsteSoft
In article <nick+-0907951257520001@ehdup-a-3.rmt.net.pitt.edu>,
nick+@pitt.edu ( nick.c ) wrote:
> In article <chrisman-0907950551370001@modem171.ucdavis.edu>,
> chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
>
> >One thing you can do is delete the application itself!
> >
> >(There's a cute program somewhere called Cheshire Cat which
demonstrates this.)
>
>
> I remember that one, was the code for that ever made
> available? It was a neat effect, and I don't know
> how one would do that - since the program would have
> to quit itself before deleting itself.
It's easy to write. You don't even have to do anything fancy. After you
prepare the necessary parameters, deleting the file takes only three
calls:
CloseResFile
FSDelete (or PBDelete)
ExitToShell
Just be sure all three are in memory. Neither of the first two calls is
going to move the code, and you don't care if the third one does.
-Ron Hunsinger
+++++++++++++++++++++++++++
>From troika@panix.com (Mark Coniglio)
Date: Mon, 10 Jul 1995 08:51:58 -0500
Organization: Troika Ranch
In article <3tqbik$s9j@redstone.interpath.net>, "Marjorie L. Rhyne"
<mrhyne@phenix.pdial.interpath.net> wrote:
> > >One thing you can do is delete the application itself!
> > >
It might be simpler to have the program delete a specific resource
from itself - one that it looks for each time it boots. If you wanted
to be really mean, you could delete one of the CODE resources which
would cause the program to crash as soon as it attempted to load that
resource.
The first suggestion would probably be enought to stop the average user.
-- MC
--
Mark Coniglio -- Troika Ranch / Dance Theater
mail: troika@panix.com
http: www.art.net/Studios/Performance/Dance/Troika_Ranch/TroikaHome.html
+++++++++++++++++++++++++++
>From ray@icon.net (Ray Hatfield)
Date: 10 Jul 1995 23:11:02 GMT
Organization: (ICON) InterConnect Online, Inc.
In article <nick+-0907951257520001@ehdup-a-3.rmt.net.pitt.edu>,
nick+@pitt.edu ( nick.c ) wrote:
> In article <chrisman-0907950551370001@modem171.ucdavis.edu>,
> chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
>
> >One thing you can do is delete the application itself!
> >
> >(There's a cute program somewhere called Cheshire Cat which
demonstrates this.)
>
>
> I remember that one, was the code for that ever made
> available? It was a neat effect, and I don't know
> how one would do that - since the program would have
> to quit itself before deleting itself.
>
I missed part of this thread, so I have no idea what you're talking about, but;
It seems that you *might* be able to call DetachResource() to separate
your running app from the file on disk (like an INIT?) and then delete
yourself? You'd have to close the application file, but you wouldn't
necessarily have to *quit* the program. I've never done it - just a
thought.
The more I think about that, the more interesting this seems. If anyone
knows more I'd love to hear some thoughts on it.
-Ray
+++++++++++++++++++++++++++
>From stay@park.uvsc.edu (Steve Taylor)
Date: 14 Jul 1995 13:04:55 -0600
Organization: Utah Valley State College, Orem, Utah
Peter N Lewis (peter@stairways.com.au) wrote:
: In article <rvtaylorDB085H.AtD@netcom.com>, rvtaylor@netcom.com (Richard
: Taylor) wrote:
: >I have had a couple of betas that "expire" at a certain point after being
: >installed. Has anyone seen any source code used to accomplish this? I
: >assume that the expiration function is not so dumb as to be fooled by
: >someone changing the system date after. Can anyone point me in the right
: >direction on this?
: Well, this code certainly is that dumb, but thats my intention. The
: purpose of the expirey code is to convince my silly beta testers to update
: to the current version.
[Peter's Code deleted]
Peter's code is more flexible than mine (with seperate checks for
old and completely expired). For variety, here's my solution (in C).
This is intended to be put in a header file and included various
places. This is so the code actually gets duplicated everywhere the
macro is used, which makes it harder to disable, if you care about
that sort of thing.
Also, using a compiler-defined symbol for the date would be much
preferrable than the replace-the-constants system I'm using.
//
// Header file for the Beta Alert.
// This file has macros for including in your source to show an alert and quit
// when the application is older than a certain number of days.
// This should only be used for beta versions that are expected to be updated
// frequently, as this behaviour will really irritate legitimate users.
//
// There is no corresponding source file to this file, just use the macros here.
// The reason I'm using macros here is so you can include the code several places
// and slightly discourage hackers.
//
// Copyright) 1995 Steven H. Taylor. All Rights Reserved.
//
#define BETA 1 // if true, check for date limitation
#ifdef BETA
#include <OSUtils.h>
#define kOldDays 180L // around 6 months
#define kSecsPerDay 3600L
#define kBetaAlertID 405 // message alert complaining about an old beta
#define REL_YEAR 1995 // release year, etc.
#define REL_MONTH 7
#define REL_DAY 8
// plug in release dates here
#define DOBETAALERT\
{\
DateTimeRec xxxTheDate;\
unsigned long xxxTheDateSecs;\
unsigned long xxxTheSecs;\
unsigned long xxx1, xxx2;\
\
xxxTheDate.year = REL_YEAR;\
xxxTheDate.month = REL_MONTH;\
xxxTheDate.day = REL_DAY;\
xxxTheDate.hour = 0;\
xxxTheDate.minute = 0;\
xxxTheDate.second = 0;\
xxxTheDate.dayOfWeek = 0;\
\
DateToSeconds(&xxxTheDate, &xxxTheDateSecs);\
GetDateTime(&xxxTheSecs);\
xxx1 = kOldDays;\
xxx2 = kSecsPerDay;\
\
if (xxxTheSecs > xxxTheDateSecs + (xxx1 * xxx2)) {\
StopAlert(kBetaAlertID, NULL);\
ExitToShell();\
}\
}\
#else // BETA is not defined
#define DOBETAALERT // nothing
#endif
--
-- Steve Taylor (stay@wahoo.com or stay@park.uvsc.edu)
--
-- "Ha Ha," said Eeyore bitterly. "Merriment and what-not.
-- Don't apologize. It's just what *would* happen."
+++++++++++++++++++++++++++
>From bc@wetware.com (monsieur HAINEUX)
Date: 17 Jul 1995 18:29:18 GMT
Organization: Castle Wetware
In a simple proof that this margin is too narrow to contain,
I have shown that
"Source code to limit the life of the app"
is to
comp.sys.FOO.programmer.BAR
as
"Does the refrigerator light REALLY go out when you close the door?"
is to
*.[physics|puzzles]{.*}
mr HEINOUS
the solution, for those that care:
1) The fridge light is friends with the Heisenberg Uncertainty Principle,
and therefore you cannot decide if the light is REALLY off or not, because
the lightbulb is actually smart enough to see what you're up to, trick you
into thinking you know what the answer is, and then promptly change its
behavior.
2) There is NO way to create ANY program that runs only until some
specified time, because, since I can see your code, I can make a patch
that will trick your code into thinking it is working correctly.
Now, if people would offer programs or source to problem 2, we could
actually PLAY this game, but as I said, it's Heisenberg-complete, so
there, nyah.
---------------------------
End of C.S.M.P. Digest
**********************